package com.glodon.async.threadpool.questions;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * JIT即时编译是在运行时动态编译字节码为机器码，相当于是在运行时对已编译代码的优化重新进行编译
 * 结论：反射不适用去修改属性值
 * @Author: lilin
 * @Date: 2022/8/16
 */
public class AnswerQuestions01 {

    /**
     * 反射修改值演示
     * 修改：CAPACITY = 200;
     */
    public static void testDemo01() throws Exception {
        // 通过反射获取字段：CAPACITY
        Field capacityField = ReflectObject.class.getDeclaredField("CAPACITY");
        // 关闭安全检查（private权限）
        capacityField.setAccessible(true);

        // 获取字段的修饰符
        Field modifiers = Field.class.getDeclaredField("modifiers");
        modifiers.setAccessible(true);
        modifiers.setInt(capacityField, capacityField.getModifiers() & ~Modifier.FINAL);
        capacityField.set(null, 30);
        System.out.println(capacityField.getInt(null));
        System.out.println(ReflectObject.getCapacity());
    }

    /**
     * 修改ReflectObject#CAPACITY为数学运算后，会变成什么样？
     * 修改：CAPACITY = Math.abs(-200);
     */
    public static void testDemo02() throws Exception {
        // 通过反射获取字段：CAPACITY
        Field capacityField = ReflectObject.class.getDeclaredField("CAPACITY");
        // 关闭安全检查（private权限）
        capacityField.setAccessible(true);

        // 获取字段的修饰符
        Field modifiers = Field.class.getDeclaredField("modifiers");
        modifiers.setAccessible(true);
        modifiers.setInt(capacityField, capacityField.getModifiers() & ~Modifier.FINAL);
        capacityField.set(null, 30);
        System.out.println(capacityField.getInt(null));
        System.out.println(ReflectObject.getCapacity());
    }

    /**
     * 热点代码优化，发现
     * JIT：如果一个表达式E已经经过计算，并且从先前的计算到本次计算E中的所有变量值保持不变，
     * 那么E在此次计算中就是公共子表达式。此时只需要使用之前E的计算结果即可。
     * 修改：CAPACITY = 200;
     */
    public static void testDemo03() throws Exception {
        // 热点代码，JIT优化
        for (int i = 0; i < 10000; i++) {
            ReflectObject.getCapacity();
        }

        // 通过反射获取字段：CAPACITY
        Field capacityField = ReflectObject.class.getDeclaredField("CAPACITY");
        // 关闭安全检查（private权限）
        capacityField.setAccessible(true);

        // 获取字段的修饰符
        Field modifiers = Field.class.getDeclaredField("modifiers");
        modifiers.setAccessible(true);
        modifiers.setInt(capacityField, capacityField.getModifiers() & ~Modifier.FINAL);
        capacityField.set(null, 30);

        System.out.println(capacityField.getInt(null));
        System.out.println(ReflectObject.getCapacity());

    }


    /**
     * 两次热点代码优化，会发现，结果时而30，时而200
     * 修改：CAPACITY = 200;
     */
    public static void testDemo04() throws Exception {
        // 热点代码，JIT优化
        for (int i = 0; i < 10000; i++) {
            ReflectObject.getCapacity();
        }

        // 通过反射获取字段：CAPACITY
        Field capacityField = ReflectObject.class.getDeclaredField("CAPACITY");
        // 关闭安全检查（private权限）
        capacityField.setAccessible(true);

        // 获取字段的修饰符
        Field modifiers = Field.class.getDeclaredField("modifiers");
        modifiers.setAccessible(true);
        modifiers.setInt(capacityField, capacityField.getModifiers() & ~Modifier.FINAL);
        capacityField.set(null, 30);

        // 热点代码，JIT优化
        for (int i = 0; i < 10000; i++) {
            ReflectObject.getCapacity();
        }

        System.out.println(capacityField.getInt(null));
        System.out.println(ReflectObject.getCapacity());

    }

    /**
     * JIT优化
     */
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 20; i++) {
            AnswerQuestions01.testDemo01();
        }
    }

}
